// Copyright (c) 2025, 大连理工大学 (Dalian University of Technology)
//
// Licensed under the Mulan PSL v2.
// You can use this file according to the terms and conditions of the Mulan PSL v2.
// You may obtain a copy of the License at
//
//     http://license.coscl.org.cn/MulanPSL2
//
// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. SEE THE MULAN PSL v2
// FOR MORE DETAILS.

#include "SubcaseRepository.h"

#include "Utility/Logging/SGLogger.h"

#include "DBManager/Repository/HDF5/Base/HDF5RepositoryMacro.h"

void* NewSubcaseRepository (SG::DBManager::HDF5Database& dataBase)
{
    return ( void* ) new SG::DBManager::HDF5::SubcaseRepository (dataBase);
};
void DelSubcaseRepository (void* Rep)
{
    delete static_cast<SG::DBManager::HDF5::SubcaseRepository*> (Rep);
};
bool H5SubcaseRepositoryFunPReg =
    SG::DBManager::HDF5Database::RegRepoFunP (typeid (ISubcaseRepository).hash_code (), { NewSubcaseRepository, DelSubcaseRepository });

using namespace SG::DBManager::HDF5;

SubcaseRepository::SubcaseRepository (HDF5Database& H5DataBaseSP) : m_H5DataBase (H5DataBaseSP)
{
    std::string path = "/SG/INPUT/PARAMETER/CASECC/SUBCASE";

    if (!m_H5DataBase.GetFile ()->exist (path))
    {
        HighFive::DataSetCreateProps props;
        props.add (HighFive::Chunking ({ 32 * 1024 / sizeof (SG::DBManager::HDF5::SUBCASE) }));  ///< 设置数据块大小
        m_H5DataBase.GetFile ()->createDataSet (path,
                                                HighFive::DataSpace ({ 0 }, { HighFive::DataSpace::UNLIMITED }),
                                                HighFive::create_datatype<SG::DBManager::HDF5::SUBCASE> (),
                                                props,
                                                {},
                                                true);  ///< 创建数据集
    }
}

SubcaseRepository::~SubcaseRepository ()
{}

void SubcaseRepository::Initial (SG::Utility::SGParameter entity)
{
    std::string SubcaseStr = entity.PrettyPrintJsonString ();  // 待初始化的参数字面量
    auto        dataset    = m_H5DataBase.GetFile ()->getDataSet ("/SG/INPUT/PARAMETER/CASECC/SUBCASE");
    bool const  ishave     = dataset.hasAttribute ("Subcase");
    if (ishave)
    {
        std::string oriStr;  // j记录先前存在的参数字面量
        dataset.getAttribute ("Subcase").read (oriStr);
        SGWarn << "For unexpected operations, the Subcase is initialized twice\nOriginal Subcase:" << oriStr;
        SGWarn << "New Subcase:" << SubcaseStr;
        dataset.deleteAttribute ("Subcase");
    }
    dataset.createAttribute<std::string> ("Subcase", SubcaseStr);

    return;
}

SG::Utility::SGParameter SubcaseRepository::GetSubcase ()
{
    auto       dataset = m_H5DataBase.GetFile ()->getDataSet ("/SG/INPUT/PARAMETER/CASECC/SUBCASE");
    bool const ishave  = dataset.hasAttribute ("Subcase");
    if (!ishave)
    {
        return {};
    }
    std::string str;
    dataset.getAttribute ("Subcase").read (str);
    return SG::Utility::SGParameter (str);
}
